package cn.com.miao.lynx.plugin.storage.service.impl;

import cn.com.miao.lynx.plugin.storage.exception.StorageException;
import cn.com.miao.lynx.plugin.storage.model.StorageResponse;
import cn.com.miao.lynx.plugin.storage.service.StorageService;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;

import java.io.*;

/**
 * LocalStorageService
 *
 * @title: LocalStorageService
 * @description:
 * @author: dengmiao
 * @create: 2020-01-10 15:38
 **/
public class LocalStorageService implements StorageService {

    private String path;

    private Boolean haveCreatePath = false;

    public LocalStorageService() {
        this(System.getProperty("user.home"));
    }

    public LocalStorageService(String path) {
        this.path = path;
    }

    @Override
    public StorageResponse upload(String objectName, byte[] bytes) throws StorageException {
        path = getFileUploadPath();
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(new File(path + objectName));
            fileOutputStream.write(bytes);
        } catch (IOException e) {
            throw new StorageException("Write file error!");
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    throw new StorageException("Write file error!");
                }
            }
        }
        return null;
    }

    @Override
    public StorageResponse upload(String objectName, InputStream inputStream) throws StorageException {
        File file = new File(this.getFileUploadPath(), objectName);
        if(file.exists()){
            throw new IllegalArgumentException("相同KEY的文件已存在");
        }
        FileOutputStream output = null;
        try {
            file.createNewFile();
            output = new FileOutputStream(file);
            IoUtil.copy(inputStream, output);
            output.flush();
        } catch (IOException e) {
            throw new StorageException("存储文件失败：" + e);
        }finally {
            if(output != null){
                try {
                    output.close();
                } catch (IOException e) {
                    throw new StorageException("存储文件失败：" + e);
                }
            }
        }
        return null;
    }

    @Override
    public StorageResponse upload(String objectName, String localFile) throws StorageException {
        try {
            FileInputStream inputStream = new FileInputStream(new File(localFile));
            upload(objectName, inputStream);
        } catch (FileNotFoundException e) {
            throw new StorageException("存储文件失败：" + e);
        }
        return null;
    }

    @Override
    public void download(String objectName, String localFile) throws StorageException {
        throw new UnsupportedOperationException("本地存储不支持该操作");
    }

    @Override
    public void delete(String objectName) throws StorageException {
        new File(this.getFileUploadPath(), objectName).delete();
    }

    private String getFileUploadPath() {
        //如果没有写文件上传路径,保存到临时目录
        if (StrUtil.isEmpty(path)) {
            return System.getProperty("java.io.tmpdir");
        } else {
            //判断有没有结尾符,没有得加上
            if (!path.endsWith(File.separator)) {
                path = path + File.separator;
            }
            //判断目录存不存在
            if (!haveCreatePath) {
                File file = new File(path);
                file.mkdirs();
                haveCreatePath = true;
            }
            return path;
        }
    }

    public byte[] getBytes(String key) {
        String filePath = getFileUploadPath() + key;
        File file = new File(filePath);
        FileInputStream fileInputStream = null;
        byte[] bytes = new byte[(int) file.length()];
        try {
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(bytes);
            return bytes;
        } catch (IOException e) {
            throw new StorageException("Read file error!");
        } finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new StorageException("Read file error!");
            }
        }
    }
}
